---
title: MediaLibrary (next)
description: A library that provides access to the device's media library.
sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-media-library/next'
packageName: 'expo-media-library'
iconUrl: '/static/images/packages/expo-media-library.png'
platforms: ['android', 'ios', 'tvos']
isNew: true
---

import APISection from '~/components/plugins/APISection';
import { APIInstallSection } from '~/components/plugins/InstallSection';
import { Collapsible } from '~/ui/components/Collapsible';
import { SnackInline } from '~/ui/components/Snippet';

`expo-media-library` provides access to the user's media library, allowing apps to read existing images and videos, as well as save new ones.

> **warning** On Android, full access to the media library (the main purpose of this package) is allowed only for apps that require broad access to photos. See [details on Google Play's Photo and Video Permissions policy](https://support.google.com/googleplay/android-developer/answer/14115180).

## Installation

<APIInstallSection />

## Usage

<Collapsible summary="Add a new asset from the web">
<SnackInline label="Add a new asset from the web" dependencies={['expo-file-system', 'expo-image', 'expo-media-library']}>

```tsx
import { View, Text } from 'react-native';
import { Image } from 'expo-image';
import { useEffect, useState } from 'react';
import { File, Paths } from 'expo-file-system';
import { Asset, requestPermissionsAsync } from 'expo-media-library/next';

export default function SaveToMediaLibraryExample() {
  const [asset, setAsset] = useState<Asset | null>(null);

  const downloadFile = async () => {
    const url = 'https://picsum.photos/200/300';
    const destinationFile = new File(Paths.cache, 'test_image.jpg');
    if (destinationFile.exists) {
      return destinationFile;
    } else {
      return File.downloadFileAsync(url, destinationFile);
    }
  };

  useEffect(() => {
    const downloadAndSaveAsset = async () => {
      const file = await downloadFile();
      const { status } = await requestPermissionsAsync();
      if (status !== 'granted') {
        return;
      }
      const asset = await Asset.create(file.uri);
      setAsset(asset);
    };

    downloadAndSaveAsset();
  }, []);

  return (
    <View>
      {asset ? (
        <>
          <Text>{asset.id}</Text>
          <Image source={{ uri: asset.id }} style={{ width: 200, height: 300 }} />
        </>
      ) : (
        <Text>Downloading and creating asset...</Text>
      )}
    </View>
  );
}
```

</SnackInline>
</Collapsible>

<Collapsible summary="Retrieve asset properties">
<SnackInline label="Retrieve asset properties" dependencies={["expo-media-library"]}>

```tsx
import { View, Text } from 'react-native';
import { useEffect, useState } from 'react';
import { AssetField, MediaType, Query, requestPermissionsAsync } from 'expo-media-library/next';

export default function RetrievingAssetPropertiesExample() {
  const [assetInfo, setAssetInfo] = useState<{
    id: string;
    filename: string;
    mediaType: string;
    width: number;
    height: number;
    creationTime: number | null;
    modificationTime: number | null;
  } | null>(null);

  useEffect(() => {
    const querySomeAsset = async () => {
      const { status } = await requestPermissionsAsync();
      if (status !== 'granted') {
        return;
      }

      const [asset] = await new Query().limit(1).eq(AssetField.MEDIA_TYPE, MediaType.IMAGE).exe();

      if (asset) {
        const filename = await asset.getFilename();
        const mediaType = (await asset.getMediaType()).toString();
        const width = await asset.getWidth();
        const height = await asset.getHeight();
        const creationTime = await asset.getCreationTime();
        const modificationTime = await asset.getModificationTime();
        setAssetInfo({
          id: asset.id,
          filename,
          mediaType,
          width,
          height,
          creationTime,
          modificationTime,
        });
      } else {
        console.log('No assets found in the media library.');
      }
    };

    querySomeAsset();
  }, []);

  return (
    <View>
      {assetInfo ? (
        <View>
          <Text>Asset ID: {assetInfo.id}</Text>
          <Text>Filename: {assetInfo.filename}</Text>
          <Text>Media Type: {assetInfo.mediaType}</Text>
          <Text>
            Dimensions: {assetInfo.width} x {assetInfo.height}
          </Text>
          <Text>
            Creation Time:{' '}
            {assetInfo.creationTime
              ? new Date(assetInfo.creationTime).toLocaleString()
              : 'Unavailable'}
          </Text>
          <Text>
            Modification Time:{' '}
            {assetInfo.modificationTime
              ? new Date(assetInfo.modificationTime).toLocaleString()
              : 'Unavailable'}
          </Text>
        </View>
      ) : (
        <Text>Fetching asset ...</Text>
      )}
    </View>
  );
}
```

</SnackInline>
</Collapsible>

<Collapsible summary="Create a new album">
<SnackInline label="Create a new album" dependencies={["expo-media-library"]}>

```tsx
import { View, Text, FlatList, Image, Button } from 'react-native';
import { useState } from 'react';
import {
  Asset,
  AssetField,
  MediaType,
  Query,
  requestPermissionsAsync,
  Album,
} from 'expo-media-library/next';

export default function CreateAlbumExample() {
  const [assets, setAssets] = useState<Asset[]>([]);
  const [album, setAlbum] = useState<Album | null>(null);
  const [albumTitle, setAlbumTitle] = useState<string>('');

  const createAlbumWithAsset = async () => {
    await requestPermissionsAsync();

    const [asset] = await new Query().limit(1).eq(AssetField.MEDIA_TYPE, MediaType.IMAGE).exe();

    if (!asset) {
      console.log('No assets found in the media library.');
      return;
    }

    const newAlbum = await Album.create('MyNewAlbum', [asset]);

    setAlbum(newAlbum);
    setAlbumTitle(await newAlbum.getTitle());
    const albumAssets = await newAlbum.getAssets();
    setAssets(albumAssets);
  };

  return (
    <View style={{ flex: 1, padding: 20 }}>
      <Button title="Create Album and Add Asset" onPress={createAlbumWithAsset} />

      {assets.length > 0 ? (
        <>
          <Text style={{ marginTop: 20, fontSize: 18, fontWeight: 'bold' }}>
            Assets in {albumTitle}:
          </Text>
          <FlatList
            data={assets}
            keyExtractor={item => item.id}
            renderItem={({ item }) => (
              <View style={{ marginVertical: 10 }}>
                <Image
                  source={{ uri: item.id }}
                  style={{ width: 100, height: 100, borderRadius: 8 }}
                />
              </View>
            )}
          />
        </>
      ) : (
        <Text style={{ marginTop: 20 }}>{album ? 'Album is empty.' : 'No album created yet.'}</Text>
      )}
    </View>
  );
}
```

</SnackInline>
</Collapsible>

## API

<APISection packageName="expo-media-library-next" apiName="MediaLibrary (next)" />
